package e2e

import (
	"testing"

	"github.com/lab-online/pkg/auth"
	"github.com/lab-online/pkg/e2e"
	"github.com/lab-online/pkg/resp"
	"github.com/stretchr/testify/assert"
)

type createClassSuccessResp struct {
	ID          uint   `json:"id"`
	Name        string `json:"name"`
	Description string `json:"description"`
	CourseID    uint   `json:"courseID"`
	Teacher     string `json:"teacher"`
}

func (ctx *context) Case1() (string, func(*testing.T)) {
	adminBearerToken := ctx.GenBearerToken("admin001", auth.RoleAdmin)
	return "管理员创建班级", func(t *testing.T) {
		t.Skip("请求参数错误")
		response := ctx.JSONRequest(&e2e.Request{
			Method: "POST",
			Path:   "/api/v1/classes",
			Body: map[string]any{
				"name":        "class 1",
				"description": "class 1 description",
				"courseID":    1,
				"teacher":     "admin001",
			},
			Header: map[string]string{
				"Authorization": adminBearerToken,
			},
		})

		assert.Equal(t, 201, response.Code)

		body := e2e.JSONBodyParser[resp.SuccessRespBody[createClassSuccessResp]](response)

		assert.Equal(t, 20200, body.Code)
		assert.NotEmpty(t, body.Data)
		assert.LessOrEqual(t, uint(1), body.Data.ID)
		assert.Equal(t, "class 1", body.Data.Name)
		assert.Equal(t, "class 1 description", body.Data.Description)
		assert.Equal(t, uint(1), body.Data.CourseID)
		assert.Equal(t, "admin001", body.Data.Teacher)
	}
}

func (ctx *context) Case2() (string, func(*testing.T)) {
	adminBearerToken := ctx.GenBearerToken("admin001", auth.RoleAdmin)
	return "管理员不可创建教师不存在的班级", func(t *testing.T) {
		t.Skip("Todo")
		response := ctx.JSONRequest(&e2e.Request{
			Method: "POST",
			Path:   "/api/v1/classes",
			Body: map[string]any{
				"name":        "class 1",
				"description": "class 1 description",
				"courseID":    1,
				"teacher":     "!teacher",
			},
			Header: map[string]string{
				"Authorization": adminBearerToken,
			},
		})

		assert.NotEqual(t, 201, response.Code)

		body := e2e.JSONBodyParser[resp.SuccessRespBody[createClassSuccessResp]](response)

		assert.NotEqual(t, 20200, body.Code)
		assert.Empty(t, body.Data)
	}
}

func (ctx *context) Case3() (string, func(*testing.T)) {
	teacherSelfToken := ctx.GenBearerToken("teacher1", auth.RoleTeacher)
	return "教师创建教师为自己的班级", func(t *testing.T) {
		t.Skip("请求参数错误")
		response := ctx.JSONRequest(&e2e.Request{
			Method: "POST",
			Path:   "/api/v1/classes",
			Body: map[string]any{
				"name":        "class 1",
				"description": "class 1 description",
				"courseID":    1,
				"teacher":     "teacher1",
			},
			Header: map[string]string{
				"Authorization": teacherSelfToken,
			},
		})

		assert.Equal(t, 201, response.Code)

		body := e2e.JSONBodyParser[resp.SuccessRespBody[createClassSuccessResp]](response)

		assert.Equal(t, 20200, body.Code)
		assert.NotEmpty(t, body.Data)
		assert.LessOrEqual(t, uint(1), body.Data.ID)
		assert.Equal(t, "class 1", body.Data.Name)
		assert.Equal(t, "class 1 description", body.Data.Description)
		assert.Equal(t, uint(1), body.Data.CourseID)
		assert.Equal(t, "teacher1", body.Data.Teacher)
	}
}

func (ctx *context) Case4() (string, func(*testing.T)) {
	teacherSelfToken := ctx.GenBearerToken("teacher1", auth.RoleTeacher)
	return "教师无权限创建教师不是自己的班级", func(t *testing.T) {
		t.Skip("请求参数错误")
		response := ctx.JSONRequest(&e2e.Request{
			Method: "POST",
			Path:   "/api/v1/classes",
			Body: map[string]any{
				"name":        "class 1",
				"description": "class 1 description",
				"courseID":    1,
				"teacher":     "teacher2",
			},
			Header: map[string]string{
				"Authorization": teacherSelfToken,
			},
		})

		assert.Equal(t, 403, response.Code)

		body := e2e.JSONBodyParser[resp.FailedRespBody[string]](response)

		assert.Equal(t, 40201, body.Code)
		assert.NotEmpty(t, body.Err)
		assert.IsType(t, "", body.Err)
	}
}
